package com.lanxiao.cloud.common.fill;

import cn.hutool.core.collection.CollUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author ：qiaoliang
 * @date ：2021-04-02
 */
public interface IFillHandleService<T,V,I> {

  void handle(List<T> list, FillHandle<T,V,I> fillHandle);

  FillType type();

  /**
   *  数据处理时所需内容（ID,USERID等）
   *
   * @author ：qiaoliang
   * @param list : 需处理集合
   * @param fillHandles : 处理函数
   * @return java.util.List<I>
   * @date 2021-04-08 17:36
   */
  default List<I> functionResult(List<T> list, FillHandle<T,V,I> fillHandles){
    return list.parallelStream().filter(Objects::nonNull)
        .map(o -> fillHandles.getFunctions().parallelStream().map(fillHandle -> fillHandle.apply(o))
            .filter(Objects::nonNull).collect(Collectors.toList())).distinct().flatMap(Collection::parallelStream)
        .filter(Objects::nonNull).distinct().collect(Collectors.toList());
  }

  /**
   *  数据处理结果回填
   *
   * @author ：qiaoliang
   * @param list : 回填类集合
   * @param fillHandles : 处理函数
   * @param map : 回填数据《key-value》
   * @return void
   * @date 2021-04-09 10:53
   */
  default void appointmentResult(List<T> list, FillHandle<T,V,I> fillHandles, Map<I,V> map){
    if(CollUtil.isEmpty(map)){
      return;
    }
    Log log = LogFactory.getLog(IFillHandleService.class);
    list.parallelStream().filter(Objects::nonNull).forEach(l->
        Stream.iterate(0, i -> i + 1).limit(fillHandles.getFunctions().size()).forEach(i -> {
      try{
        final FillAppointment<T, V> fillAppointment = fillHandles
            .getFillAppointments().get(i);
        final Function<T, I> function = fillHandles.getFunctions().get(i);

        if(Objects.isNull(function) || Objects.isNull(fillAppointment)){
          return;
        }
        final I apply = function.apply(l);
        if(apply instanceof ArrayList) {
          List<I> data = (List<I>)apply;
          data.forEach(d->{
            final V v = map.get(d);
            if(Objects.isNull(v)){
              return;
            }
            fillAppointment.fill(l, v);
          });
          return;
        }
        if(Objects.isNull(apply)){
          return;
        }
        final V v = map.get(apply);
        if(Objects.isNull(v)){
          return;
        }
        fillAppointment.fill(l, v);
      }catch (Exception e){
        log.debug("单条数据问题造成回填出现异常e:{}", e);
      }
    }));
  }

}
